const express = require('express');
const { Op } = require('sequelize');
const router = express.Router();
const { Article, User } = require('../../models');
const { success, failure } = require('../../utils/responses');
const { NotFound } = require('http-errors');

/**
 * 公共方法：白名单过滤
 * @param req
 * @returns {{title, content: *}}
 */
const filterBody = (req) => {
  const { title, content, status } = req.body;
  return { title, content, status };
};

/**
 * 公共方法：关联用户数据
 * @returns {{include: [{as: string, model, attributes: string[]}], attributes: {exclude: string[]}}}
 */
const getCondition = () => {
  return {
    attributes: { exclude: ['UserId'] },
    include: [
      {
        model: User,
        as: 'user',
        attributes: ['id', 'username', 'avatar'],
      },
    ],
  };
};

/**
 * 公共方法：查询当前文章
 */
const getArticle = async (req) => {
  // 获取文章 ID
  const { id } = req.params;

  const condition = getCondition();

  // 查询当前文章
  const article = await Article.findByPk(id, condition);

  // 如果没有找到，就抛出异常
  if (!article) {
    throw new NotFound(`ID: ${id}的文章未找到`);
  }

  return article;
};

/**
 * 查询文章列表
 * GET /admin/articles
 */
router.get('/', async (req, res) => {
  try {
    const query = req.query;

    // 当前是第几页，如果不传，那就是第一页
    const currentPage = Math.abs(Number(query.current)) || 1;
    // 每页显示多少条数据，如果不传，那就显示10条
    const pageSize = Math.abs(Number(query.pageSize)) || 10;
    // 计算 offset
    const offset = (currentPage - 1) * pageSize;

    const condition = {
      ...getCondition(),
      order: [['id', 'DESC']],
      limit: pageSize,
      offset,
      where: {},
    };
    // 查询被软删除的数据
    if (query.deleted === 'true') {
      condition.paranoid = false;
      condition.where.deletedAt = {
        [Op.not]: null,
      };
    }
    if (query.title) {
      condition.where.title = {
        [Op.like]: `%${query.title}%`,
      };
    }
    if (query.content) {
      condition.where.content = {
        [Op.like]: `%${query.content}%`,
      };
    }
    if (query.status) {
      condition.where.status = query.status;
    }
    // 查询数据
    const { count, rows } = await Article.findAndCountAll(condition);

    success(res, '查询文章列表成功', {
      data: rows,
      total: count,
    });
  } catch (error) {
    failure(res, error);
  }
});
/**
 * 查询文章详情
 * GET /admin/articles/:id
 */
router.get('/:id', async (req, res) => {
  try {
    // 查询数据
    const article = await getArticle(req);
    success(res, '查询文章详情成功', { data: article });
  } catch (error) {
    failure(res, error);
  }
});
/**
 * 创建文章
 * GPOST /admin/articles/add
 */
router.post('/add', async (req, res) => {
  try {
    // 创建文章
    let params = filterBody(req);
    params.userId = req.user.id;
    const article = await Article.create(params);
    success(res, '创建文章成功', { data: article }, 201);
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 删除到回收站
 * POST /admin/articles/delete
 */
router.post('/delete', async function (req, res) {
  try {
    const { id } = req.body;
    // 查询id是否为非软删除数据
    await Article.destroy({ where: { id: id } });
    success(res, '已删除到回收站。');
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 从回收站恢复
 * POST /admin/articles/restore
 */
router.post('/restore', async function (req, res) {
  try {
    const { id } = req.body;

    await Article.restore({ where: { id: id } });
    success(res, '已恢复成功。');
  } catch (error) {
    failure(res, error);
  }
});
/**
 * 彻底删除
 * POST /admin/articles/force_delete
 */
router.post('/force_delete', async function (req, res) {
  try {
    const { id } = req.body;

    await Article.destroy({
      where: { id: id },
      force: true,
    });
    success(res, '已彻底删除。');
  } catch (error) {
    failure(res, error);
  }
});
/**
 * 更新文章
 * PUT /admin/articles/:id
 */
router.put('/:id', async (req, res) => {
  try {
    const article = await getArticle(req);
    // 更新文章
    const updateArticle = await article.update(filterBody(req));
    success(res, '更新文章成功', { data: updateArticle });
  } catch (error) {
    failure(res, error);
  }
});

module.exports = router;
